import numpy as np
import pandas as pd
from dash import html
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from src.core.churn_prediction.random_forest_classifier import model_analysis

def churn_risk(TARGET_SOFTWARE:str) -> Figure:
    try:
        df = pd.read_csv(f'src/core/churn_prediction/analyze_results/{TARGET_SOFTWARE}.csv')
    except:
        model_analysis(TARGET_SOFTWARE)
        df = pd.read_csv(f'src/core/churn_prediction/analyze_results/{TARGET_SOFTWARE}.csv')

    risk_values = df['流失风险'].clip(0, 1)

    candidate_bins = [
        0,
        np.percentile(risk_values, 25),
        np.percentile(risk_values, 50),
        np.percentile(risk_values, 75),
        0.1, 0.2, 0.3, 1.0
    ]
    
    bins = np.round(np.unique([x for x in candidate_bins if 0 <= x <= 1]), 3)

    if len(bins) < 2:
        bins = np.array([0.0, 1.0])

    label_templates = ['极低风险', '低风险', '中风险', '较高风险', '高风险', '严重风险']
    n_bins = len(bins) - 1
    labels = label_templates[:n_bins] if n_bins <= 6 else [f'Level {i+1}' for i in range(n_bins)]
    
    df['风险等级'] = pd.cut(risk_values, bins=bins, labels=labels, include_lowest=True, duplicates='drop')

    fig = plt.figure(figsize=(18, 6))
    plt.subplots_adjust(wspace=0.3)

    plt.subplot(1, 3, 1)
    sns.histplot(df['流失风险'], bins=20, kde=True, color='#4B8BBE')
    plt.title('用户流失风险分布',pad=20)
    plt.xlabel('流失风险概率')
    plt.ylabel('用户数量')
    plt.grid(axis='y', alpha=0.3)

    plt.subplot(1, 3, 2)
    box = sns.boxplot(
        x='风险等级', 
        y='流失风险', 
        hue='风险等级',
        data=df, 
        palette='RdYlGn_r',
        linewidth=1.5, 
        fliersize=4, 
        width=0.6,
        legend=False
    )
    plt.title('风险等级分布箱线图', pad=20)
    plt.xlabel('风险分级')
    plt.ylabel('风险值分布')
    plt.grid(axis='y', alpha=0.3)

    plt.subplot(1, 3, 3)
    risk_counts = df['风险等级'].value_counts()
    colors = ['#66c2a5', '#fee08b', '#fc8d62', '#d53e4f']
    plt.pie(risk_counts, labels=risk_counts.index, autopct='%.1f%%',
            colors=colors, startangle=90, textprops={'fontsize':12})
    plt.title('风险等级占比分布', pad=20)

    plt.tight_layout()

    high_risk_users = df.sort_values('流失风险', ascending=False).head(5).copy()
    high_risk_users['流失风险'] = high_risk_users['流失风险'].apply(lambda x: f"{x:.1%}")

    high_risk_users_div = html.Div([
        html.Table([
            html.Tr([html.Td("用户ID"), html.Td("流失风险")]),
            html.Tr([
                html.Td(high_risk_users['USERID'].iloc[0]), 
                html.Td(high_risk_users['流失风险'].iloc[0])
                ]), 
            html.Tr([
                html.Td(high_risk_users['USERID'].iloc[1]), 
                html.Td(high_risk_users['流失风险'].iloc[1])
                ]), 
            html.Tr([
                html.Td(high_risk_users['USERID'].iloc[2]), 
                html.Td(high_risk_users['流失风险'].iloc[2])
                ]), 
            html.Tr([
                html.Td(high_risk_users['USERID'].iloc[3]), 
                html.Td(high_risk_users['流失风险'].iloc[3])
                ]), 
            html.Tr([
                html.Td(high_risk_users['USERID'].iloc[4]), 
                html.Td(high_risk_users['流失风险'].iloc[4])
                ])
        ], style={'width': '100%', 'display': 'table', 'tableLayout': 'fixed'})
    ])

    return fig, high_risk_users_div

if __name__ == '__main__':
    TARGET_SOFTWARE = 'EXCEL.EXE'
    fig, user = churn_risk(TARGET_SOFTWARE)
    print(user['USERID'].iloc[0])
    print(user['流失风险'].iloc[0])